<template>
	<div class="sticky" :style="{ height: height + 'px', zIndex: zIndex }">
		<div
			:class="className"
			:style="{
				top: isSticky ? stickyTop + 'px' : '',
				zIndex: zIndex,
				position: position,
				width: width,
				height: height + 'px'
			}"
		>
			<slot>
				<div>sticky</div>
			</slot>
		</div>
	</div>
</template>

<script>
export default {
	name: "Sticky",
	props: {
		stickyTop: {
			type: Number,
			default: 0
		},
		zIndex: {
			type: Number,
			default: 1
		},
		className: {
			type: String,
			default: ""
		}
	},
	data() {
		return {
			active: false,
			position: "",
			width: undefined,
			height: undefined,
			isSticky: false
		};
	},
	mounted() {
		this.height = this.$el.getBoundingClientRect().height;
		window.addEventListener("scroll", this.handleScroll);
		window.addEventListener("resize", this.handleResize);
	},
	activated() {
		this.handleScroll();
	},
	destroyed() {
		window.removeEventListener("scroll", this.handleScroll);
		window.removeEventListener("resize", this.handleResize);
	},
	methods: {
		sticky() {
			if (this.active) {
				return;
			}
			this.position = "fixed";
			this.active = true;
			this.width = this.width + "px";
			this.isSticky = true;
		},
		handleReset() {
			if (!this.active) {
				return;
			}
			this.reset();
		},
		reset() {
			this.position = "";
			this.width = "auto";
			this.active = false;
			this.isSticky = false;
		},
		handleScroll() {
			const width = this.$el.getBoundingClientRect().width;
			this.width = width || "auto";
			const offsetTop = this.$el.getBoundingClientRect().top;
			if (offsetTop < this.stickyTop) {
				this.sticky();
				return;
			}
			this.handleReset();
		},
		handleResize() {
			if (this.isSticky) {
				this.width = this.$el.getBoundingClientRect().width + "px";
			}
		}
	}
};
</script>
